#include "../StdInc.h"

namespace GSTrader
{
	namespace Util
	{
		CThreadRWLock::CThreadRWLock()
		{
			m_nReadLockCount = NULL;
			m_bWriteLock = FALSE;
			m_bWaitLock = FALSE;
		}

		CThreadRWLock::~CThreadRWLock()
		{
			assert(m_nReadLockCount == NULL);
			assert(m_bWriteLock == FALSE);
			assert(m_bWaitLock == FALSE);
		}

		void CThreadRWLock::WriteLock()
		{
			m_bWriteLock = TRUE;
			m_WriteMutex.Lock();
		}

		void CThreadRWLock::UnWriteLock()
		{
			m_WriteMutex.Unlock();
			m_bWriteLock = FALSE;
		}

		bool CThreadRWLock::ReadLock(bool bSync)
		{
			if (!bSync && (m_bWriteLock || m_bWaitLock))
			{
				return false;
			}

			m_ReadMutex.Lock();
			if (m_nReadLockCount == NULL)
			{
				assert(!m_bWaitLock);
				m_bWaitLock = TRUE;
				m_WriteMutex.Lock();
				m_bWaitLock = FALSE;
			}
			m_nReadLockCount++;
			m_ReadMutex.Unlock();
			return true;
		}

		void CThreadRWLock::UnReadLock()
		{
			m_ReadMutex.Lock();
			assert(m_nReadLockCount);
			m_nReadLockCount--;
			if (m_nReadLockCount == NULL)
			{
				m_WriteMutex.Unlock();
			}
			m_ReadMutex.Unlock();
		}
	}
}